package com.yhm.pagination;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import java.util.UUID;

import org.apache.log4j.Logger;
import org.apache.struts2.StrutsStatics;
import org.apache.struts2.components.Component;
import org.apache.struts2.dispatcher.StrutsRequestWrapper;

import com.opensymphony.xwork2.util.ValueStack;

/***
 * 分页逻辑Bean分页标签处理类
 * 该类需要从值栈当中取值.
 * @author 杨华明
 * @date 2012.9.28
 */
public class Pages extends Component {
 
	private Logger logger=Logger.getLogger(getClass());
	private PageUtil pageUtil;
	private String includes;
	private String name="";//分页参数前缀[标签的名称]
	private String pagerForm;
	private Integer seaJS;
	/**接收分页参数*/
	public Pages(ValueStack arg0,PageUtil pageUtil){
		this(arg0);
	}
	public Pages(ValueStack arg0) {
		super(arg0);
		logger.debug("构造");
	}
	/**序列化参数.将客户传递过来的参数转换为地址栏传递的参数形式*/
	protected String serialize(){
		StringBuilder perUrl = new StringBuilder("");
		//把参数及其值拼凑成字符串(客户端自定义的参数)
		if (includes != null && includes.trim().length() > 0) {
			String[] perm = includes.split(",");
			for (int i = 0; i < perm.length; i++) {
				String permName = perm[i];
				Object obje = stack.findValue(permName);
				String value=(obje==null?"":obje).toString();
				perUrl.append(String.format("&%s=%s", permName,value));
			}
		}		
		return perUrl.toString();
	}
	/**生成分页片段.并显示在网页上*/
	@Override
	public boolean start(Writer writer) {
		logger.debug("start");
		boolean result = super.start(writer);
		//不需要给a标签传递地址
		Map<String, Object> cont = stack.getContext();
		StrutsRequestWrapper request = (StrutsRequestWrapper)cont.get(StrutsStatics.HTTP_REQUEST);
		String url = (String) request.getAttribute("javax.servlet.forward.request_uri");
		try {
			writer.write(getTools3(url));	
		} catch (IOException e) {
			e.printStackTrace();
			logger.error("组件初始化失败:"+e);
		}
		return result;
	}
	/**
	 * @param url上一页，下一页连接的地址
	 * @param uuid 作为分页标签的唯一ID*/
	public String getTools2(String url,String uuid){
		logger.debug("请求地址:"+url);
		StringBuffer str=new StringBuffer("");
		str.append(String.format("<div class='%s'>",uuid));		
		if (pageUtil.getTotalPage()>=1 ) {//总页数必须大于等于1
			str.append(String.format("<span>共%d条记录</span>", pageUtil.getTotalCount()));	
			//1.当前页等于1时(首页，第一页、1的显示情况)
			if (pageUtil.getCurrentPage() == 1) { //当前页为第一页
				str.append("<span class='disabled'>首页</span>");
				str.append("<span class='disabled'>前一页</span>");
			}else {//当前页大于1时(首页，第一页、(1就不一定要显示了)的显示情况)				
				str.append(String.format("<a href='%s' title='%d'>首页</a>", url,pageUtil.getFirstPage()));
				str.append(String.format("<a href='%s' title='%d'>前一页</a>",url,pageUtil.getPrevPage()));
			}
			//2.1 根据当前页计算要显示的起始和终止页数.1(超过5个按5个显示,不足5个全部显示)	
			int start=1,end=1;
			if(pageUtil.getTotalPage()<=5){ //总页数小于5,全部显示出来.
				start=pageUtil.getFirstPage();
				end=pageUtil.getLastPage();
			}else{    //1.总页数大于5.
				if(pageUtil.getCurrentPage()<=2){//总页数大于5.当当前页小于2,那么显示前5条.
					start=pageUtil.getFirstPage();
					end=5;
				}else if(pageUtil.getCurrentPage()>pageUtil.getTotalPage()-2){//总页数大于5.当前页+2已经大于总页数了。取最后5条
					start=pageUtil.getLastPage()-4;
					end=pageUtil.getLastPage();
				}else { //2.总页数大于5.取当前页的前后两条
					start=pageUtil.getCurrentPage()-2;
					end=pageUtil.getCurrentPage()+2;
				}
			}
			//2.当前页等于中间页数的情况1 < current < totalPage.只显示当前页附近的5页,小于5页，有几页显示几页
			for (int i = start; i <= end; i++) {
				 if (pageUtil.getCurrentPage() == i) { // 当前页要加粗显示
   				    str.append(String.format("<span class='current' title='%d'>%d</span>", i,i));
				 }else {
				   str.append(String.format("<a href='%s' title='%d'>%d</a>",url,i,i));
			   }
			}
			//3.当前页等于总页数时(后一页、末页的显示情况
			if (pageUtil.getCurrentPage() ==  pageUtil.getTotalPage()) { //当前页为最后一页
				str.append("<span class='disabled'>后一页</span>");
				str.append("<span class='disabled'>末页</span>");
			}else {
				str.append(String.format("<a href='%s' title='%d'>后一页</a>", url,pageUtil.getNextPage()));
				str.append(String.format("<a href='%s' title='%d'>末页</a>", url,pageUtil.getLastPage()));
			}
			str.append(String.format("<span>当前[%d/%d]页</span>", pageUtil.getCurrentPage(),pageUtil.getTotalPage()));
		}
		str.append("</div>");
		return str.toString();
	}
	/**通过传递进来的窗体进行提交数据参数
	 * 增加分页插件的单机事件
	 * 如果指定了表参数，则把表单为表单指定参数，并提交表单
	 * 如果没有指定表单则以get方式提交参数，可能存在中文参数问题
	 * 只要通过修改tomcat的server.xml文件的Service标签下的子标签Connector，增加一个属性 URIEncoding="UTF-8"*/
	public String getTools3(String url){
		StringBuffer str=new StringBuffer("");
		String uuid="A"+UUID.randomUUID().toString().replace("-", "").toUpperCase();//随机样式名称.唯一区分
		str.append(getTools2(url,uuid));
		if(getPagerForm()!=null&&getPagerForm().length()>0){
		   String jsStr="";
		   if(getSeaJS()==0){
			   jsStr=readScriptFile("pagination1.js");//使用原生Jquery
		   }else {
			   jsStr=readScriptFile("pagination2.js");//使用seaJs模块
		   }
		   jsStr=String.format(jsStr,uuid,getPagerForm(),getName(),getPageUtil().getPageSize(),getName(),getPagerForm(),getIncludes());
		   str.append(jsStr);
		}
		return str.toString();
	}
	/**分页计算工具*/
	public PageUtil getPageUtil() {
		return pageUtil;
	}
	/**分页计算工具*/
	public void setPageUtil(PageUtil pageUtil) {
		this.pageUtil = pageUtil;
	}
	/**分页对象的名称.作为分页参数的前缀比如，
	 * 当name="page"时应传递:page.currentPage,
	 * 取出来是是加了:name.*/
	public String getName() {
		return (name!=null&&name.trim().length()>0)?name+".":"";
	}
	/**分页对象的名称.作为分页参数的前缀比如，
	 * 当name="page"时应传递:page.currentPage*/
	public void setName(String name) {
		this.name = name;
	}
	/**可传递的参数列表(作为get参数传递)*/
	public String getIncludes() {
		logger.debug("getIncludes="+includes);
		return includes==null?"":includes;
	}
	/**可传递的参数(作为get参数传递)*/
	public void setIncludes(String includes) {
		logger.debug("setIncludes="+includes);
		this.includes = includes==null?"":includes;
	}
	/**页面传递过来的。用户生成的提交的表单的名字
	 * 如果为空则通过a标签提交*/
	public String getPagerForm() {
		return pagerForm==null?"":pagerForm;
	}
	/**页面传递过来的。用户生成的提交的表单的名字
	  * 如果为空则通过a标签提交*/
	public void setPagerForm(String pagerForm) {
		this.pagerForm = pagerForm==null?"":pagerForm;
	}
	/**读取脚本文件
	 *@param fileName 读取的文件名
	 **/
	public String readScriptFile(String fileName){
		DataInputStream in=new DataInputStream(getClass().getClassLoader().getResourceAsStream(fileName));
		byte[] buf=null;
		try {
			buf=new byte[in.available()];
			in.readFully(buf);
		} catch (Exception e) {
			logger.debug("数据输出流:",e);
			e.printStackTrace();
		}
		return new String(buf);
	}
	/**Jquery是否使用seajs包装0，不使用，1使用*/
	public Integer getSeaJS() {
		return seaJS==null?0:seaJS;
	}
	/**Jquery是否使用seajs包装0，不使用，1使用*/
	public void setSeaJS(Integer seaJS) {
		this.seaJS = seaJS;
	}
}
